#include "bulletHell.h"
#include <stdlib.h>
#include <Windows.h>
#include <vector>
#include <time.h>

using namespace std;

BulletHell::BulletHell(){
	timePerFireball = FIREBALL_START_PERIOD;
	timeSinceLastFireball = 0.0f;
}

BulletHell::~BulletHell(){

}

void BulletHell::initialize(HWND hwnd){
	Game::initialize(hwnd);

	if(!nebulaTexture.initialize(graphics,NEBULA_IMAGE))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing nebula texture"));

	if (!playerTexture.initialize(graphics,PLAYER_IMAGE))
        throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing player texture"));

    if (!fireballTexture.initialize(graphics,FIREBALL_IMAGE))
        throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing fireball texture"));

	if(!nebula.initialize(graphics,0,0,0,&nebulaTexture))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing nebula"));

    if (!player.initialize(graphics,0,0,0,&playerTexture))
        throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing player"));

	initFireball = Image();
	if(!initFireball.initialize(graphics,0,0,0,&fireballTexture))
		throw(GameError(gameErrorNS::FATAL_ERROR, "Error initializing fireball image"));
	
	bullets = BulletList(initFireball);
	
    // place player in center of screen
	playerPosition = vector<float>(2);
	playerPosition[0] = GAME_WIDTH*0.5f  - player.getWidth()*0.5f;
	playerPosition[1] = GAME_HEIGHT*0.5f - player.getHeight()*0.5f;
    player.setX(playerPosition[0]);
    player.setY(playerPosition[1]);

	//initialize seed
	srand(time(NULL));
	int x = 0;
	int y = 0;
	generateXY(x, y);

	bullets.addNewBullet((float) x, (float) y, playerPosition[0], playerPosition[1]);

    /*ship.setFrames(SHIP_START_FRAME, SHIP_END_FRAME);   // animation frames
    ship.setCurrentFrame(SHIP_START_FRAME);     // starting frame
    ship.setFrameDelay(SHIP_ANIMATION_DELAY);*/

	playerVelocity = vector<float>(2);
	playerVelocity[0] = 0.0;
	playerVelocity[1] = 0.0;

	nearBullets = vector<Bullet>();

    return;
}

void BulletHell::generateXY(int &x, int &y) {
	int side = rand() % 4;
	switch (side)
	{
		case 0:
			x = rand() % GAME_WIDTH;
			y = 0;
			break;
		case 1:
			x = 0;
			y = rand() % GAME_HEIGHT;
			break;
		case 2:
			x = rand() % GAME_WIDTH;
			y = GAME_HEIGHT;
			break;
		case 3:
			x = GAME_WIDTH;
			y = rand() % GAME_HEIGHT;
			break;
		default:
			break;
	}
}

void BulletHell::update(){
	updatePlayerPos();
}

void BulletHell::updatePlayerPos(){
	//first update velocities
	if(input->isKeyDown(PLAYER_RIGHT_KEY))
    {
        if (playerVelocity[0] < MAX_SPEED){
			playerVelocity[0] += ACCELERATION*frameTime;
		}
    }
	else if (playerVelocity[0] > 0.0){
		playerVelocity[0] = max(0.0, playerVelocity[0] - ACCELERATION*frameTime);
	}

    if(input->isKeyDown(PLAYER_LEFT_KEY))             // if move left
    {
        if (playerVelocity[0] > -MAX_SPEED){
			playerVelocity[0] -= ACCELERATION*frameTime;
		}
    }
	else if (playerVelocity[0] < 0.0){
		playerVelocity[0] = min(0.0, playerVelocity[0] + ACCELERATION*frameTime);
	}

    if(input->isKeyDown(PLAYER_UP_KEY))               // if move up
    {
        if (playerVelocity[1] > -MAX_SPEED){
			playerVelocity[1] -= ACCELERATION*frameTime;
		}
    }
	else if (playerVelocity[1] < 0.0){
		playerVelocity[1] = min(0.0, playerVelocity[1] + ACCELERATION*frameTime);
	}

    if(input->isKeyDown(PLAYER_DOWN_KEY))             // if move down
    {
        if (playerVelocity[1] < MAX_SPEED){
			playerVelocity[1] += ACCELERATION*frameTime;
		}
    }
	else if (playerVelocity[1] > 0.0){
		playerVelocity[1] = max(0.0, playerVelocity[1] - ACCELERATION*frameTime);
	}

	playerPosition[0] += playerVelocity[0]*frameTime;
	playerPosition[1] += playerVelocity[1]*frameTime;

	//wrap around window edges
	if (playerPosition[0] < -player.getWidth())
		playerPosition[0] = (float)GAME_WIDTH;

	if (playerPosition[0] > (float)GAME_WIDTH)
		playerPosition[0] = -player.getWidth();

	if (playerPosition[1] < -player.getHeight())
		playerPosition[1] = (float)GAME_HEIGHT;

	if (playerPosition[1] > (float)GAME_HEIGHT)
		playerPosition[1] = -player.getHeight();

	//set the texture's position
	player.setX(playerPosition[0]);
	player.setY(playerPosition[1]);
}

void BulletHell::ai(){
	if (timeSinceLastFireball > timePerFireball){
		int x = 0;
		int y = 0;
		generateXY(x, y);

		bullets.addNewBullet((float) x, (float) y, playerPosition[0], playerPosition[1]);
		timeSinceLastFireball = 0.0f;
		timePerFireball = max(0.2f, timePerFireball - PERIOD_CHANGE_PER_FIREBALL);
	}
	timeSinceLastFireball += frameTime;
	nearBullets = bullets.moveBullets(frameTime, playerPosition[0], playerPosition[1]);
}

void BulletHell::collisions(){
	for(auto it = nearBullets.begin(); it != nearBullets.end(); ++it) {
		//check for collision
	}
}

void BulletHell::render(){
	graphics->spriteBegin();                // begin drawing sprites

    nebula.draw();                          // add the orion nebula to the scene
    player.draw();                          // add the planet to the scene
	bullets.draw();

    graphics->spriteEnd();                  // end drawing sprites
}